#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
FileHive 图标转换脚本
将icon/icon.png转换为项目所需的高质量图标文件

功能：
1. 生成Golang编译可执行文件所需的图标（.ico格式）
2. 生成Vue前端所需的图标文件（favicon.ico及各种尺寸的PNG）

特点：
- 使用LANCZOS重采样算法获得最清晰的图标
- 生成多分辨率ICO文件支持高DPI显示
- 手动构建ICO文件确保质量和兼容性
- 对小图标应用锐化和对比度增强
"""

import os
import struct
from PIL import Image, ImageFilter, ImageEnhance
import io
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def create_icon_layer(source_img, size):
    """创建指定尺寸的图标层"""
    # 高质量多步缩放
    temp_img = source_img.copy()
    current_size = max(source_img.size)
    
    # 逐步缩小
    while current_size > size * 2:
        new_size = current_size // 2
        temp_img = temp_img.resize((new_size, new_size), Image.Resampling.LANCZOS)
        current_size = new_size
    
    # 最终缩放
    final_img = temp_img.resize((size, size), Image.Resampling.LANCZOS)
    
    # 对小图标应用锐化和增强
    if size <= 48:
        try:
            # 锐化
            final_img = final_img.filter(ImageFilter.UnsharpMask(radius=0.8, percent=150, threshold=3))
            # 增强对比度
            enhancer = ImageEnhance.Contrast(final_img)
            final_img = enhancer.enhance(1.15)
            # 增强锐度
            sharpness = ImageEnhance.Sharpness(final_img)
            final_img = sharpness.enhance(1.2)
        except:
            pass
    
    return final_img

def image_to_png_bytes(img):
    """将PIL图像转换为PNG字节数据"""
    with io.BytesIO() as output:
        img.save(output, format='PNG', optimize=True)
        return output.getvalue()

def create_ico_manually(source_path, target_path):
    """手动创建ICO文件以确保多层支持"""
    try:
        sizes = [16, 20, 24, 32, 40, 48, 64, 96, 128, 256]
        
        with Image.open(source_path) as source_img:
            if source_img.mode != 'RGBA':
                source_img = source_img.convert('RGBA')
            
            logger.info(f"源图像: {source_img.size}, 模式: {source_img.mode}")
            
            # 创建所有尺寸的图标
            icon_data = []
            for size in sizes:
                img = create_icon_layer(source_img, size)
                png_data = image_to_png_bytes(img)
                icon_data.append((size, png_data))
                logger.info(f"  创建 {size}x{size}, PNG数据大小: {len(png_data)} bytes")
        
        # 手动构建ICO文件
        with open(target_path, 'wb') as f:
            # ICO文件头 (6 bytes)
            f.write(struct.pack('<HHH', 0, 1, len(icon_data)))  # 保留字, 类型, 图像数量
            
            # 计算目录条目偏移量
            directory_size = 6 + (16 * len(icon_data))  # 文件头 + 目录条目
            data_offset = directory_size
            
            # 写入目录条目 (每个16 bytes)
            for size, png_data in icon_data:
                width = size if size < 256 else 0   # 256以上用0表示
                height = size if size < 256 else 0
                f.write(struct.pack('<BBBBHHII', 
                    width,          # 宽度
                    height,         # 高度  
                    0,              # 调色板颜色数 (PNG为0)
                    0,              # 保留字
                    1,              # 颜色平面
                    32,             # 位深度
                    len(png_data),  # 图像数据大小
                    data_offset     # 图像数据偏移量
                ))
                data_offset += len(png_data)
            
            # 写入图像数据
            for size, png_data in icon_data:
                f.write(png_data)
        
        # 验证生成的文件
        file_size = os.path.getsize(target_path)
        logger.info(f"✓ ICO文件生成成功: {target_path}")
        logger.info(f"文件大小: {file_size} bytes")
        logger.info(f"包含 {len(icon_data)} 个图像层")
        
        # 验证文件可以被PIL读取
        try:
            with Image.open(target_path) as ico_img:
                logger.info(f"验证: 主要尺寸 {ico_img.size}, 模式 {ico_img.mode}")
        except Exception as e:
            logger.warning(f"PIL验证警告: {e}")
        
        return True
        
    except Exception as e:
        logger.error(f"创建ICO文件失败: {e}")
        return False

def create_enhanced_png_icon(source_path, target_path, size):
    """创建增强的PNG图标"""
    try:
        with Image.open(source_path) as source_img:
            if source_img.mode != 'RGBA':
                source_img = source_img.convert('RGBA')
            
            enhanced_img = create_icon_layer(source_img, size)
            
            # 确保目标目录存在
            os.makedirs(os.path.dirname(target_path), exist_ok=True)
            
            enhanced_img.save(target_path, format='PNG', optimize=True)
            logger.info(f"✓ 增强PNG图标: {target_path} ({size}x{size})")
            return True
    except Exception as e:
        logger.error(f"创建PNG图标失败: {e}")
        return False

def generate_frontend_icons(source_path):
    """生成前端所需的所有图标文件"""
    logger.info("生成前端图标文件...")
    
    # 前端需要的PNG图标尺寸
    frontend_png_sizes = [16, 32, 48, 72, 96, 128, 144, 152, 192, 384, 512]
    
    # 生成标准PNG图标
    for size in frontend_png_sizes:
        target_path = f"../frontend/public/icon-{size}x{size}.png"
        create_enhanced_png_icon(source_path, target_path, size)
    
    # 生成manifest专用图标
    create_enhanced_png_icon(source_path, "../frontend/public/manifest-icon-192.png", 192)
    create_enhanced_png_icon(source_path, "../frontend/public/manifest-icon-512.png", 512)
    
    # 生成Apple Touch图标
    create_enhanced_png_icon(source_path, "../frontend/public/apple-touch-icon.png", 180)
    
    # 生成favicon.ico（包含多个尺寸）
    favicon_path = "../frontend/public/favicon.ico"
    if create_ico_manually(source_path, favicon_path):
        logger.info(f"✓ 前端favicon.ico生成成功: {favicon_path}")
    else:
        logger.error(f"前端favicon.ico生成失败: {favicon_path}")

def main():
    """主函数"""
    logger.info("FileHive 图标转换脚本")
    logger.info("=" * 50)
    
    source_icon = "icon.png"
    if not os.path.exists(source_icon):
        logger.error(f"源图标文件不存在: {source_icon}")
        return 1
    
    # 1. 生成后端Go程序所需的图标文件
    logger.info("生成后端图标文件...")
    
    # 确保后端assets目录存在
    os.makedirs("../backend-go/assets", exist_ok=True)
    
    # 创建高质量多层ICO文件
    go_ico_path = "../backend-go/assets/app.ico"
    if create_ico_manually(source_icon, go_ico_path):
        logger.info("✓ 后端ICO文件生成成功！")
    else:
        logger.error("后端ICO文件生成失败")
        return 1
    
    # 创建增强的PNG图标
    png_sizes = [256, 512]
    for size in png_sizes:
        png_path = f"../backend-go/assets/app-{size}.png"
        create_enhanced_png_icon(source_icon, png_path, size)
    
    # 也更新一个大尺寸PNG作为主图标
    create_enhanced_png_icon(source_icon, "../backend-go/assets/app.png", 512)
    
    # 2. 生成前端Vue项目所需的图标文件
    generate_frontend_icons(source_icon)
    
    logger.info("=" * 50)
    logger.info("图标转换完成！")
    
    print("\n图标质量优化说明:")
    print("✓ ICO文件包含10个精确尺寸 (16到256像素)")
    print("✓ 使用PNG格式存储，保持透明度和最佳质量")
    print("✓ 小图标应用了锐化、对比度和清晰度增强")
    print("✓ 多步缩放算法确保最佳质量")
    print("✓ 手动构建ICO文件确保所有层都包含")
    
    print("\n生成的文件:")
    print("后端文件:")
    print("  - ../backend-go/assets/app.ico (Windows可执行文件图标)")
    print("  - ../backend-go/assets/app.png (主图标)")
    print("  - ../backend-go/assets/app-256.png")
    print("  - ../backend-go/assets/app-512.png")
    
    print("\n前端文件:")
    print("  - ../frontend/public/favicon.ico (网站图标)")
    print("  - ../frontend/public/icon-*.png (各种尺寸的应用图标)")
    print("  - ../frontend/public/manifest-icon-*.png (PWA清单图标)")
    print("  - ../frontend/public/apple-touch-icon.png (iOS添加到主屏幕图标)")
    
    print("\n如果图标仍然模糊:")
    print("1. 可能是Windows图标缓存问题")
    print("2. 运行清除缓存脚本: cd ../backend-go && scripts\\clear-icon-cache.bat")
    print("3. 或删除: %localappdata%\\IconCache.db 然后重启")
    print("4. 确保在高DPI显示器上查看")
    
    return 0

if __name__ == "__main__":
    import sys
    sys.exit(main()) 